using System;
using System.Runtime.InteropServices;
using Tao.OpenGl;
using Tao.Platform.Windows;

namespace Dida
{
	public class ManagedGlArea : Gtk.EventBox
	{
		IntPtr hDC;
		IntPtr hRC;

		bool failed = false;

		public ManagedGlArea()
		{
			SetSizeRequest(640, 480);
		}

		protected override void OnRealized()
		{
			base.OnRealized();
			InitOpenGl();
		}

		protected override void OnUnrealized()
		{
			FreeOpenGl();
			base.OnUnrealized();
		}

		private void InitOpenGl()
		{
			IntPtr hWnd = External.gdk_win32_drawable_get_handle(GdkWindow.Handle);
			hDC = User.GetDC(hWnd);
						
			Gdi.PIXELFORMATDESCRIPTOR pfd;
			pfd.nSize = (short)Marshal.SizeOf(typeof(Gdi.PIXELFORMATDESCRIPTOR));
			pfd.nVersion = 1;
			pfd.dwFlags = Gdi.PFD_DRAW_TO_WINDOW|Gdi.PFD_SUPPORT_OPENGL|Gdi.PFD_DOUBLEBUFFER;
			pfd.iPixelType = Gdi.PFD_TYPE_RGBA;
			pfd.cColorBits = 16;
			pfd.cRedBits = 0;
			pfd.cRedShift = 0;
			pfd.cGreenBits = 0;
			pfd.cGreenShift = 0;
			pfd.cBlueBits = 0;
			pfd.cBlueShift = 0;
			pfd.cAlphaBits = 0;
			pfd.cAlphaShift = 0;
			pfd.cAccumBits = 0;
			pfd.cAccumRedBits = 0;
			pfd.cAccumGreenBits = 0;
			pfd.cAccumBlueBits = 0;
			pfd.cAccumAlphaBits = 0;
			pfd.cDepthBits = 16;
			pfd.cStencilBits = 0;
			pfd.cAuxBuffers = 0;
			pfd.iLayerType = 0;
			pfd.bReserved = 0;
			pfd.dwLayerMask = 0;
			pfd.dwVisibleMask = 0;
			pfd.dwDamageMask = 0;
			int pixelFormat = Gdi.ChoosePixelFormat(hDC, ref pfd);
			if (pixelFormat == 0)
			{
				FreeOpenGl();
				failed = true;
				return;
			}

			if (!Gdi.SetPixelFormat(hDC, pixelFormat, ref pfd))
			{
				FreeOpenGl();
				failed = true;
				return;
			}

			hRC = Wgl.wglCreateContext(hDC);
			if (hRC == IntPtr.Zero)
			{
				FreeOpenGl();
				failed = true;
				return;
			}

			if (!Wgl.wglMakeCurrent(hDC, hRC))
			{
				FreeOpenGl();
				failed = true;
				return;
			}
		}

		private void FreeOpenGl()
		{
			if (hRC != IntPtr.Zero)
			{
				Wgl.wglMakeCurrent(IntPtr.Zero, IntPtr.Zero);
				Wgl.wglDeleteContext(hRC);
				hRC = IntPtr.Zero;
			}

			if (hDC != IntPtr.Zero)
			{
				User.ReleaseDC(GdkWindow.Handle, hDC);
				hDC = IntPtr.Zero;
			}
		}

		public void BeginGl()
		{
			Wgl.wglMakeCurrent(hDC,hRC);
		}

		public void EndGl()
		{
			Gdi.SwapBuffers(hDC);
		}

		protected override bool OnExposeEvent(Gdk.EventExpose evnt)
		{
			if (failed)
			{
				/*Gdk.Pixbuf pixbuf = Rsvg.Pixbuf.FromFileAtSize(
					"C:/Documents and Settings/Lieven/Desktop/bom.svg",
					Allocation.Width, Allocation.Height);

				evnt.Window.DrawPixbuf(new Gdk.GC(evnt.Window), pixbuf, 
					0, 0, 0, 0, pixbuf.Width, pixbuf.Height, Gdk.RgbDither.Normal, 0, 0);*/

				return true;
			}
			else
			{
				return base.OnExposeEvent(evnt);
			}
		}
	}

	internal static class External
	{
		[DllImport("libgdk-win32-2.0-0.dll")]
		public extern static IntPtr gdk_win32_drawable_get_handle(IntPtr window);
	}
}